/**
 * Check if an element has a class
 * @param {HTMLElement} ele
 * @param {string} cls
 * @returns {boolean}
 */
export function hasClass(ele: HTMLElement, cls: string) {
  return !!ele.className.match(new RegExp("(\\s|^)" + cls + "(\\s|$)"));
}

/**
 * Add class to element
 * @param {HTMLElement} ele
 * @param {string} cls
 */
export function addClass(ele: HTMLElement, cls: string) {
  if (!hasClass(ele, cls)) ele.className += " " + cls;
}

/**
 * Remove class from element
 * @param {HTMLElement} ele
 * @param {string} cls
 */
export function removeClass(ele: HTMLElement, cls: string) {
  if (hasClass(ele, cls)) {
    const reg = new RegExp("(\\s|^)" + cls + "(\\s|$)");
    ele.className = ele.className.replace(reg, " ");
  }
}

/**
 * @param {string} path
 * @returns {Boolean}
 */
export function isExternal(path: string) {
  const isExternal = /^(https?:|http?:|mailto:|tel:)/.test(path);
  return isExternal;
}

// 字符串下划线转驼峰
export const formatToHump = (value: string) => {
  return value.replace(/\_(\w)/g, (_, letter) => letter.toUpperCase())
}

// 字符串驼峰转下划线
export const formatToLine = (value: string) => {
  return value.replace(/([A-Z])/g, '_$1').toLowerCase()
}

/**
 * 数据对象key 驼峰下划线互相转化
 * @param {Object} data 需要转换的对象
 * @param {String} type hump-转驼峰 toLine-转下划线
 */
export const formatHumpLineTransfer = (data: any, type = 'hump') => {
  let hump = ''
  // 转换对象中的每一个键值为驼峰的递归
  const formatTransferKey = (data: any) => {
    if (data instanceof Array) {
      data.forEach(item => formatTransferKey(item))
    } else if (data instanceof Object) {
      for (const key in data) {
        hump = type === 'hump' ? formatToHump(key) : formatToLine(key)
        data[hump] = data[key]
        if (key !== hump) {
          delete data[key]
        }
        if (data[hump] instanceof Object) {
          formatTransferKey(data[hump])
        }
      }
    } else if (typeof data === 'string') {
      data = type === 'hump' ? formatToHump(data) : formatToLine(data)
    }
  }
  formatTransferKey(data)
  return data
}

// 过滤关键字段
export const filterKey = (obj, temp_key="temp_") => {
	const isObject = (o:any) => {
		return (typeof o === 'object' || typeof o === 'function') && o !== null
	}
	if (!isObject(obj)) {
		throw new Error('obj 不是一个对象！')
	}
	for (const key in obj) {
		if(key.includes(temp_key)) {
			delete obj[key]
		}else if(isObject(obj[key])) {
			filterKey(obj[key], temp_key)
		}
	}
	return obj
}

type Trigger = 'blur' | 'change'
export const newRule = (required: boolean = true, message: string = '必填项', trigger: Trigger) => {
	return { required, message, trigger };
}

// 获取rgba随机色
export const getRGBAColor = (a?:number): string => {
  const r = Math.floor(Math.random()*255)
  const g = Math.floor(Math.random()*255)
  const b = Math.floor(Math.random()*255)
	return `rgba(${r},${g},${b},${a || 1})`;
}

/**
 * 树形结构化
 * @param { Array } data
 * @param { number } pidSum
 * @param { string } children
 * @returns { Array }
 */
const filterArray = (
  data: { id: number | string; pid: number | string }[],
  pidSum: number = 1,
  children: string = "children"
): Array<any> => {
  const result: any = []; // 存放结果集
  const itemMap: any = {}; //
  for (const item of data) {
    const id = item.id;
    const pid = item.pid;

    if (!itemMap[id]) {
      itemMap[id] = {
        children: [],
      };
    }
    itemMap[id] = {
      ...item,
      children: itemMap[id][children],
    };
    const treeItem = itemMap[id];
    if (pid === pidSum) {
      result.push(treeItem);
    } else {
      if (!itemMap[pid]) {
        itemMap[pid] = {
          children: [],
        };
      }
      itemMap[pid].children.push(treeItem);
    }
  }
  return result;
};
/**
 * 生成随机数
 * @param { number } num
 * @returns
 */
const getRandom = (num: number) => {
  const random = Math.floor((Math.random() + Math.floor(Math.random() * 9 + 1)) * Math.pow(10, num - 1));
  return random;
};

/**
 * 对象数组根据某个相同的字段分组
 * @param {Array} arr 目标对象数组
 * @param {string } filed 分组字段
 * @param {string} keys 展示字段
 * @returns []
 */
const classIfyArrayGroup = (arr: [], filed: string, keys: string, children: string = "children") => {
  const temObj:any = {};
  for (let i = 0; i < arr.length; i++) {
    const item: any = arr[i];
    if (!temObj[item[filed]]) {
      temObj[item[filed]] = [item];
    } else {
      temObj[item[filed]].push(item);
    }
  }
  const resArr: { [x: string]: any }[] = [];
  Object.keys(temObj).forEach((item) => {
    resArr.push({
      [keys]: item,
      [children]: temObj[item],
    });
  });
  return resArr;
};

/**
 * 弧度=角度× π/180
 * 将-180 到 180角度值转换为弧度值
 * @param {number} degrees 角度值
 */
const degreesToRadians = (degrees: number) => {
  return Number((degrees * (Math.PI / 180)).toFixed(8));
};

/**
 * 角度 = 弧度× 180/π
 * 将弧度值转换为-180 到 180角度值
 * @param {number} radians 弧度值
 */
const radiansToDegrees = (radians: number) => {
  let degrees = radians * (180 / Math.PI);
  // 保持在 -180 到 180 的范围内
  if (degrees > 180) {
    degrees -= 360;
  } else if (degrees < -180) {
    degrees += 360;
  }
  // 保留三位小数
  return Number(degrees.toFixed(3));
};
export { filterArray, getRandom, classIfyArrayGroup, degreesToRadians, radiansToDegrees };
